<script lang="ts" setup>
import type { ArticleApi } from '#/api/core/article';

import { computed, onBeforeUnmount, onMounted, ref, shallowRef } from 'vue';
import { useRoute, useRouter } from 'vue-router';

import { Button, Form, Input, message, Select } from 'ant-design-vue';

import { getArticleCategoriesApi } from '#/api/core/article';
import { requestClient } from '#/api/request';
import axios from 'axios';
import { useAccessStore } from '@vben/stores';
const router = useRouter();
const route = useRoute();
const isEdit = computed(() => route.query.type === 'edit');

// 从 localStorage 获取文章数据
const articleData = ref<{
  article_content: string;
  article_title: string;
  article_type: string;
  id: number;
} | null>(null);
if (isEdit.value) {
  const savedData = localStorage.getItem('editArticleData');
  if (savedData) {
    articleData.value = JSON.parse(savedData);
  }
}

// 编辑器实例，必须用 shallowRef
const editorRef = shallowRef();

// 内容 HTML
const valueHtml = ref('');

// 文章分类列表
const categories = ref<ArticleApi.ArticleCategory[]>([]);

// 表单数据
const formData = ref({
  article_type: undefined as number | undefined,
  article_title: '',
  article_content: '',
});

// 表单规则
const rules = {
  article_type: [{ required: true, message: '请选择文章分类' }],
  article_title: [{ required: true, message: '请输入文章标题' }],
  article_content: [{ required: true, message: '请输入文章内容' }],
};

declare const window: any;

// 初始化编辑器
function initEditor() {
  const { createEditor, createToolbar } = window.wangEditor;

  // 编辑器配置
  const editorConfig = {
    placeholder: '请输入内容...',
    onChange(editor: any) {
      valueHtml.value = editor.getHtml();
      formData.value.article_content = editor.getHtml();
    },
    MENU_CONF: {
      uploadImage: {
        // 自定义选择图片和上传
        customBrowseAndUpload(
          insertFn: (url: string, alt?: string, href?: string) => void,
        ) {
          // 创建一个文件输入框
          const input = document.createElement('input');
          input.type = 'file';
          input.accept = 'image/*';
          input.addEventListener('change', async () => {
            const file = input.files?.[0];
            if (!file) return;

            // 检查文件大小
            if (file.size > 5 * 1024 * 1024) {
              message.error('图片大小不能超过 5MB');
              return;
            }

            // 创建 FormData 对象
            const formData = new FormData();
            formData.append('file', file);

            try {
              // 发送请求到自定义的上传接口
              const response = await requestClient.post(
                '/v1/update/resource/',
                formData,
                {
                  headers: {
                    'Content-Type': 'multipart/form-data',
                    Authorization: `Bearer ${localStorage.getItem('token')}`,
                  },
                },
              );
              // console.log('response', response);
              // 假设返回的数据中包含图片的 URL
              const imageUrl = response.url;
              // 插入图片
              insertFn(imageUrl);
              message.success('上传图片成功');
            } catch {
              message.error('上传图片失败');
              // console.error('上传图片失败', error);
            }
          });
          // 触发文件选择
          input.click();
        },
      },
      uploadVideo: {
        // 自定义选择视频和上传
        customBrowseAndUpload(
          insertFn: (url: string, alt?: string, href?: string) => void,
        ) {
          // 创建一个文件输入框
          const input = document.createElement('input');
          input.type = 'file';
          input.accept = 'video/*';
          input.addEventListener('change', async () => {
            const file = input.files?.[0];
            if (!file) return;

            // 检查文件大小
            if (file.size > 500 * 1024 * 1024) {
              message.error('视频大小不能超过 500MB');
              return;
            }

            // 创建 FormData 对象
            const formData = new FormData();
            formData.append('file', file);

            // 创建加载提示
            const hide = message.loading('视频上传中...', 0);

            try {
              const accessStore = useAccessStore();
              // 使用原生 axios 发送请求
              const response = await axios.post('https://api.cqhuanyuai.com/api/v1/update/resource/', formData, {
                headers: {
                  'Content-Type': 'multipart/form-data',
                  Authorization: `Bearer ${accessStore.accessToken}`,
                },
                timeout: 600000, // 设置超时时间为 10 分钟
                onUploadProgress: (progressEvent) => {
                  // console.log('progressEvent', progressEvent);
                },
              });
              hide(); // 关闭加载提示
              console.log('response', response);
              const videoUrl = response.data.data.url;
              insertFn(videoUrl);
              message.success('上传视频成功');
            } catch (error) {
              hide(); // 关闭加载提示
              if (axios.isAxiosError(error) && error.code === 'ECONNABORTED') {
                message.error('上传视频超时，请重试');
              } else {
                message.error('上传视频失败，请重试');
              }
              console.error('上传视频失败', error);
            }
          });
          // 触发文件选择
          input.click();
        },
      },
    },
  };

  // 创建编辑器
  editorRef.value = createEditor({
    selector: '#editor',
    html: valueHtml.value,
    config: editorConfig,
    mode: 'default',
  });

  // 创建工具栏
  createToolbar({
    editor: editorRef.value,
    selector: '#toolbar',
    mode: 'default',
    config: {},
  });

  // 如果是编辑模式，设置初始内容
  if (isEdit.value && articleData.value) {
    editorRef.value.setHtml(articleData.value.article_content);
  }
}

// 获取文章分类
async function loadCategories() {
  try {
    const response = await getArticleCategoriesApi();
    categories.value = response;
  } catch {
    message.error('获取文章分类失败');
  }
}

// 组件挂载时初始化
onMounted(async () => {
  // 先加载分类数据
  await loadCategories();

  // 如果是编辑模式且有文章数据，初始化表单
  if (isEdit.value && articleData.value) {
    // 根据文章类型名称找到对应的分类 ID
    const categoryId = articleData.value?.article_type 
      ? categories.value.find(
          (category) => category.name === articleData.value?.article_type
        )?.id
      : undefined;

    formData.value = {
      article_type: categoryId, // 使用找到的分类 ID
      article_title: articleData.value.article_title,
      article_content: articleData.value.article_content,
    };
    valueHtml.value = articleData.value.article_content;
  }

  initEditor();

  // 清除 localStorage 中的数据
  localStorage.removeItem('editArticleData');
});

// 组件销毁时，也及时销毁编辑器
onBeforeUnmount(() => {
  const editor = editorRef.value;
  if (editor === null) return;
  editor.destroy();
});

// 提交表单
async function handleSubmit() {
  try {
    const params = {
      article_type: formData.value.article_type, // 这里已经是数字 ID 了
      article_title: formData.value.article_title,
      article_content: valueHtml.value,
    };

    if (isEdit.value && articleData.value) {
      // 编辑模式
      await requestClient.post('/v1/update/article/', {
        ...params,
        id: articleData.value.id,
      });
      message.success('修改文章成功');
    } else {
      // 新增模式
      await requestClient.post('/v1/add/article/', params);
      message.success('添加文章成功');
    }

    router.push('/article/list');
  } catch {
    message.error(isEdit.value ? '修改文章失败' : '添加文章失败');
  }
}

// 返回列表
function handleBack() {
  router.push('/article/list');
}
</script>

<template>
  <div class="p-4">
    <div class="mb-4 flex items-center justify-between">
      <h2 class="text-lg font-medium">
        {{ isEdit ? '修改文章' : '添加文章' }}
      </h2>
      <Button @click="handleBack">返回列表</Button>
    </div>

    <Form
      :model="formData"
      :rules="rules"
      layout="vertical"
      @finish="handleSubmit"
    >
      <Form.Item label="文章分类" name="article_type">
        <Select
          v-model:value="formData.article_type"
          placeholder="请选择文章分类"
          style="width: 200px"
        >
          <Select.Option
            v-for="category in categories"
            :key="category.id"
            :value="category.id"
          >
            {{ category.name }}
          </Select.Option>
        </Select>
      </Form.Item>

      <Form.Item label="文章标题" name="article_title">
        <Input
          v-model:value="formData.article_title"
          placeholder="请输入文章标题"
        />
      </Form.Item>

      <Form.Item label="文章内容" name="article_content">
        <div style="border: 1px solid #ccc">
          <div id="toolbar" style="border-bottom: 1px solid #ccc"></div>
          <div id="editor" style="height: 500px"></div>
        </div>
      </Form.Item>

      <Form.Item>
        <Button html-type="submit" type="primary">提交</Button>
      </Form.Item>
    </Form>
  </div>
</template>
